package yxy.apple.database;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.transform.Transformers;

public abstract class BaseDAO<T> {

	public String tablename;

	public String getTablename() {
		return tablename;
	}

	public void setTablename(String tablename) {
		this.tablename = tablename;
	}

	/**
	 * 添加数据
	 * 
	 * @param obj
	 * @return
	 */
	public static <T> boolean add(HibernateUtil hu, T obj) {
		Session session = null;
		Transaction tran = null;
		boolean result = false;
		try {
			session = hu.getSession();
			tran = session.beginTransaction();
			session.save(obj);
			tran.commit();
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
			if (tran != null) {
				// 事物回滚
				tran.rollback();
			}
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}

		}
		return result;
	}

	/**
	 * 添加批量数据
	 * 
	 * @param obj
	 * @return
	 */
	public static <T> boolean addBatch(HibernateUtil hu, List<T> list) {
		long start = System.currentTimeMillis();

		Session session = null;
		Transaction tran = null;
		boolean result = false;
		try {
			session = hu.getSession();
			tran = session.beginTransaction();
			for (int i = 0; i < list.size(); i++) {
				session.save(list.get(i));
//				if (i % 100 == 0) {
				if (i % 99 == 0) {
					session.flush();
					session.clear();
				}
			}

			tran.commit();
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
			if (tran != null) {
				// 事物回滚
				tran.rollback();
			}
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}
		}

		return result;
	}

	/**
	 * @return 更新数据 参数为修改的主键id对象
	 */
	public static <T> boolean update(HibernateUtil hu, T object) {
		long start = System.currentTimeMillis();

		Session session = null;
		Transaction tran = null;
		boolean result = false;
		try {
			session = hu.getSession();
			tran = session.beginTransaction();
			session.update(object);// saveOrUpdate(object);//
			tran.commit();
			result = true;
		} catch (Exception e) {
			if (tran != null) {
				// 事物回滚
				tran.rollback();
			}
			// String obj = JSON.toJSONString(object);
			// System.out.println(obj);
			e.printStackTrace();
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}
		}
		return result;
	}

	/**
	 * @param <T>
	 * @return 批量更新
	 */
	public static <T> boolean updateBatch(HibernateUtil hu, List<T> list) {
		if (list == null || list.size() == 0) {
			return false;
		}
		Session session = null;
		Transaction tran = null;
		boolean result = false;
		try {
			session = hu.getSession();
			tran = session.beginTransaction();
			for (int i = 0; i < list.size(); i++) {
				session.update(list.get(i));
//				if (i % 100 == 0) {
				if (i % 99 == 0) {
					session.flush();
					session.clear();
				}
			}
			tran.commit();
			result = true;
		} catch (Exception e) {
			if (tran != null) {
				// 事物回滚
				tran.rollback();
			}
			e.printStackTrace();
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}
		}
		return result;
	}

	/**
	 * @param <T>
	 * @return 批量更新
	 */
	public static <T> boolean deleteBatch(HibernateUtil hu, List<T> list) {
		if (list == null || list.size() == 0) {
			return false;
		}
		Session session = null;
		Transaction tran = null;
		boolean result = false;
		try {
			session = hu.getSession();
			tran = session.beginTransaction();
			for (int i = 0; i < list.size(); i++) {
				session.delete(list.get(i));
//				if (i % 100 == 0) {
				if (i % 99 == 0) {
					session.flush();
					session.clear();
				}
			}
			tran.commit();
			result = true;
		} catch (Exception e) {
			if (tran != null) {
				// 事物回滚
				tran.rollback();
			}
			e.printStackTrace();
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}
		}
		return result;
	}

	/**
	 * @param c
	 * @param id 查询一条数据根据主键的id号
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T get(HibernateUtil hu, Class<?> c, int id) {
		Session session = null;
		T object = null;
		try {
			session = hu.getSession();
			object = (T) session.get(c, id);
		} catch (Exception e) {
			// XXX
			e.printStackTrace();
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}
		}
		return object;
	}

	/**
	 * @param c
	 * @param id 查询一条数据根据主键的id号
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T get(HibernateUtil hu, Class<?> c, Serializable id) {
		Session session = null;
		T object = null;
		try {
			session = hu.getSession();
			object = (T) session.get(c, id);
		} catch (Exception e) {
			// XXX
			e.printStackTrace();
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}
		}
		return object;
	}

	/**
	 * @param obj
	 * @return 删除数据
	 */
	public static <T> boolean delete(HibernateUtil hu, T obj) {
		Session session = null;
		Transaction tran = null;
		boolean result = false;
		try {
			session = hu.getSession();
			tran = session.beginTransaction();
			session.delete(obj);
			tran.commit();
			result = true;
		} catch (Exception e) {
			// XXX
			e.printStackTrace();
			if (tran != null) {
				// 事物回滚
				tran.rollback();
			}
		} finally {
			if (session != null) {
				// 关闭session
				session.close();
			}
		}
		return result;
	}

	/**
	 * @param <T>   查询多条记录
	 * @param sql   sql语句
	 * @param param 参数数组
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> query(HibernateUtil hu, String sql, String[] param) {
		List<T> list = new ArrayList<T>();
		Session session = null;
		try {
			session = hu.getSession();
			Query query = session.createQuery(sql);
			if (param != null) {
				for (int i = 0; i < param.length; i++) {
					query.setParameter(i, param[i]);
				}
			}
			list = query.list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * @param <T>   查询多条记录
	 * @param sql   sql语句
	 * @param param 参数数组
	 * @return
	 *
	 * 这个是新加的SQL查询，其他都是HQL查询
	 */
	public static <T> List<T> sqlQuery(HibernateUtil hu, String sql, String[] param) {
		List<T> list = new ArrayList<T>();
		Session session = null;
		try {
			session = hu.getSession();
			Query query = session.createSQLQuery(sql);
			if (param != null) {
				for (int i = 0; i < param.length; i++) {
					query.setParameter(i, param[i]);
				}
			}
			list = query.list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * @param <T>   查询多条记录
	 * @param sql   sql语句
	 * @param param 参数数组
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> queryLimit(HibernateUtil hu, String sql, Object[] param, int limit) {
		List<T> list = new ArrayList<T>();
		Session session = null;
		try {
			session = hu.getSession();
			Query query = session.createQuery(sql);
			if (param != null) {
				for (int i = 0; i < param.length; i++) {
					query.setParameter(i, param[i]);
				}
			}
			query.setMaxResults(limit);
			list = query.list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	@SuppressWarnings("unchecked")
	public static <T> List<T> queryByKey(HibernateUtil hu, String tablename, String key, String param) {
		List<T> list = new ArrayList<T>();
		Session session = null;
		try {
			session = hu.getSession();
			String sql = String.format("from %s as ts where ts.%s=?0", tablename, key);
			Query query = session.createQuery(sql);
			query.setParameter(0, param);

			list = query.list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * @param hu
	 * @param tablename
	 * @param key
	 * @param param
	 * @param <T>
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T queryOne(HibernateUtil hu, String tablename, String key, String param) {
		Object object = null;
		Session session = null;
		try {
			session = hu.getSession();
			String sql = String.format("from %s as ts where ts.%s=?0", tablename, key);
			Query query = session.createQuery(sql);
			if (param != null) {
				query.setParameter(0, param);
			}
			object = query.uniqueResult();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return (T) object;
	}

	/**
	 * @param sql
	 * @param param 查询单条记录
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T queryOne(HibernateUtil hu, String sql, String[] param) {
		Object object = null;
		Session session = null;
		try {
			session = hu.getSession();
			Query query = session.createQuery(sql);
			if (param != null) {
				for (int i = 0; i < param.length; i++) {
					query.setParameter(i, param[i]);
				}
			}
			object = query.uniqueResult();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return (T) object;
	}

	/**
	 * @param <T>
	 * @param sql
	 * @param param
	 * @param page
	 * @param size
	 * @return 实现分页查询
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> queryByPage(HibernateUtil hu, String sql, String[] param, int page, int size) {
		List<T> list = new ArrayList<T>();
		Session session = null;
		try {
			session = hu.getSession();
			Query query = session.createQuery(sql);
			if (param != null) {
				for (int i = 0; i < param.length; i++) {
					query.setParameter(i, param[i]);
				}
			}
			// 筛选条数
			query.setFirstResult((page - 1) * size);
			query.setMaxResults(size);
			list = query.list();
		} catch (Exception e) {
			// XXX
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * @param hql
	 * @param pras
	 * @return返回数据个数
	 */
	public static int getCount(HibernateUtil hu, String hql, String[] pras) {
		int resu = 0;
		Session s = null;
		try {
			s = hu.getSession();
			Query q = s.createQuery(hql);
			if (pras != null) {
				for (int i = 0; i < pras.length; i++) {
					q.setParameter(i, pras[i]);
				}
			}
			resu = q.list().size();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (s != null)
				s.close();
		}
		return resu;
	}

	@SuppressWarnings("unchecked")
	public static int getCountByKey(HibernateUtil hu, String tablename, String key, String param) {
		int resu = 0;
		Session session = null;
		try {
			session = hu.getSession();
			String sql = String.format("from %s as ts where ts.%s=?0", tablename, key);
			Query query = session.createQuery(sql);
			query.setParameter(0, param);

			resu = query.list().size();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}

		return resu;
	}

	public static int execBySql(HibernateUtil hu, String sql, Map<String, Object> params) {
		int res = 0;
		Session session = null;
		try {
			session = hu.getSession();
			Transaction tran = session.beginTransaction();
			Query query = session.createSQLQuery(sql);
			for (Map.Entry<String, Object> entry : params.entrySet()) {
				query.setParameter(entry.getKey(), entry.getValue());
			}
			res = query.executeUpdate();
			tran.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}

		return res;
	}

	public static <T> List<T> queryBySql(HibernateUtil hu, Class<T> classz , String sql, Map<String, Object> params) throws Exception{
		List<T> list = new ArrayList<T>();
		Session session = null;
		try {
			if(hu!=null){
				session = hu.getSession();
				NativeQuery<T> query = session.createSQLQuery(sql);
				for (Map.Entry<String, Object> entry : params.entrySet()) {
					query.setParameter(entry.getKey(), entry.getValue());
				}
				query.addEntity(classz);
				list = query.list();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}
}